package tenumn.energytech.registrys.machine.heart;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.ItemStackHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import tenumn.energytech.registrys.CapabilitiesRegistry;
import tenumn.energytech.registrys.capability.CapabilityHeart;
import tenumn.energytech.registrys.machine.MachineBlockEntity;

import javax.annotation.ParametersAreNonnullByDefault;
import java.util.Set;

@ParametersAreNonnullByDefault
public abstract class BurnerBlockEntity extends MachineBlockEntity {
    private final ItemStackHandler itemStackHandler = new ItemStackHandler(1);
    private final CapabilityHeart heart=new CapabilityHeart(0,0,Float.MAX_VALUE);
    private int fuleTick = 0;

    public BurnerBlockEntity(BlockEntityType<?> pType, BlockPos pWorldPosition, BlockState pBlockState) {
        super(pType, pWorldPosition, pBlockState);
    }


    @NotNull
    @Override
    public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
        if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
            return LazyOptional.of(() -> itemStackHandler).cast();
        if(cap==CapabilitiesRegistry.HEART_CAPABILITY&&side!=null){
            if(getHeartDirections().contains(side))
            return LazyOptional.of(()->heart).cast();
        }
        return super.getCapability(cap, side);
    }

    @Override
    protected void saveAdditional(CompoundTag pTag) {
        super.saveAdditional(pTag);
        pTag.put("Item", itemStackHandler.serializeNBT());
        pTag.putInt("FuleTick", fuleTick);
        pTag.put("Heart",heart.serializeNBT());
    }

    @Override
    public void load(CompoundTag pTag) {
        super.load(pTag);;
        itemStackHandler.deserializeNBT(pTag.getCompound("Item"));
        fuleTick = pTag.getInt("FuleTick");
        heart.deserializeNBT(pTag.getCompound("Heart"));
    }
    private final Set<Direction> heartDirections=Set.of(Direction.UP);
    protected  Set<Direction> getHeartDirections(){
        return heartDirections;
    };
    protected abstract int getHeartRise();
    @Override
    public void tick() {
        if (level instanceof ServerLevel serverLevel) {
            if(heart.getTemperature()>0){
                if(heart.getTemperature()> 1000){
                    level.playSound(null,getBlockPos(), SoundEvents.GENERIC_EXPLODE, SoundSource.BLOCKS,1,1);
                    level.setBlock(getBlockPos(), Blocks.LAVA.defaultBlockState(), 3);
                }
                for(Direction direction:getHeartDirections()) {
                    BlockEntity blockEntity = serverLevel.getBlockEntity(getBlockPos().relative(direction));
                    if (blockEntity != null)
                        blockEntity.getCapability(CapabilitiesRegistry.HEART_CAPABILITY,direction.getOpposite())
                                .ifPresent(otherHeart -> {
                                    otherHeart.rise(heart.coolDown(getHeartRise(), false), false);
                                });
                }
            }
            if (fuleTick <= 0) {
                var item = itemStackHandler.getStackInSlot(0);
                if (!item.isEmpty()) {
                    var fuleTimes = ForgeHooks.getBurnTime(item, RecipeType.SMELTING);
                    if (fuleTimes > 0) {
                        fuleTick = fuleTimes;
                        item.shrink(1);
                    }
                }
            }
            if (fuleTick > 0) {
                fuleTick--;
                heart.rise(getHeartRise(),false);
                level.blockEntityChanged(getBlockPos());
            } else {
                fuleTick = 0;
            }
        }
    }
}
